﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

/*
 *    Dim sFilename As String
            sFilename = csFilePrefix & cbSourceID.ToString & "_" & ciDataID.ToString _
                    & csFileExtension
            Return System.IO.Path.Combine(csRootDir, sFilename)    

sFileName = Me.FullPath()
        Dim objFileStream As New IO.FileStream(sFileName, FileMode.Append)

        cobjStreamWriter = New IO.StreamWriter(objFileStream)
 Me.cobjStreamWriter.WriteLine(sLines(icount))
 * */
namespace AceBots.FileMgr
{
    #region Enums
    public enum ARPacketWriterFormats : byte
    {
        FilePerReadIdSourceCSV = 0x01,
        RowPerReadIdFilePerSourceCSV = 0x02,
        RowPerPacketFilePerSourceCSV =0x03,

    }
#endregion

 
    public class ARPacketWriter
    {
        #region Constructor
        public ARPacketWriter(string psFileroot,string psDir,
            ARPacketWriterFormats pFormat, 
            bool pbIncludeTimeStamp, bool pbIncludeHeaderRow)
        {
            IncludeTimeStamp = pbIncludeTimeStamp;
            WriterFormat = pFormat;
            FileRoot = psFileroot;
            FileDir = psDir;
            ciReadingsWritten = 0;
            IncludeHeaderRow = pbIncludeHeaderRow;
        }
     
        #endregion

        #region Properties
        public bool IncludeTimeStamp { get; set;}
        public ARPacketWriterFormats WriterFormat { get; set; }
        public string FileRoot { get; set; }
        public string FileDir { get; set; }
        public bool IncludeHeaderRow { get; set; }

        private int ciReadingsWritten;
        private bool cblFileExists;
        #endregion

        #region Public Methods
        public string FilePath(short psReadID, ushort psSourceID)
        {
            string strRetVal;
            if (WriterFormat == ARPacketWriterFormats.FilePerReadIdSourceCSV)
            {
               
                strRetVal = FileRoot + psReadID.ToString() + "_" + psSourceID.ToString() + ".csv";
            }
            else
            {
                strRetVal = FileRoot + "_" + psSourceID.ToString() + ".csv";
            }
            strRetVal=System.IO.Path.Combine( FileDir,strRetVal);
            return strRetVal;
        }

        public void WriteData( AceBots.ARPacket.ARPacket pARPacket)
        {
            string strVal;
            byte bVal;
            short sVal=0;
            int iVal;
            short iReadID=0;
            short iPrevReadID = -1;
            FileStream objFileStream;
            StreamWriter objFSWriter=null;
            ARPacket.ARPacketValueTypes packetValType;

            // we only write out data packets
            if(pARPacket.IsDataPacket)
            {
                ciReadingsWritten=0;
            // if the source determines the filename then open the file
            if (this.WriterFormat == ARPacketWriterFormats.RowPerPacketFilePerSourceCSV ||
                WriterFormat == ARPacketWriterFormats.RowPerReadIdFilePerSourceCSV)
            {
                string strfilepath;
                strfilepath = this.FilePath(0, pARPacket.SourceSystemAddress);
                objFileStream = new FileStream(strfilepath, FileMode.Append);
               
                objFSWriter=new StreamWriter(objFileStream);
                if ((objFileStream.Length == 0) && IncludeHeaderRow) cWriteHeader(pARPacket, objFSWriter);

            }

            if( pARPacket.PacketType == ARPacket.ARPacketTypes.BinaryShortReadings)
            {
               while (pARPacket.GetNextReading(out iReadID, out sVal))
               {
                   if((iPrevReadID != iReadID) && (WriterFormat==ARPacketWriterFormats.FilePerReadIdSourceCSV))
                   { // need to open a new file
                       if (iPrevReadID != -1) objFSWriter.Close();// close the one that is open if one is open
                       objFileStream = new FileStream(this.FilePath(iReadID, pARPacket.SourceSystemAddress), FileMode.Append);
                       objFSWriter=new StreamWriter(objFileStream);
                       if ((objFileStream.Length == 0) && IncludeHeaderRow) cWriteHeader(pARPacket, objFSWriter);

                       iPrevReadID=iReadID;
                   }
                   WriteSingleReading(iReadID, objFSWriter, ARPacket.ARPacketValueTypes.IsShort, sVal, 0, "", 0, pARPacket.PacketType);
                   ++ciReadingsWritten;
               }
            }
            else if (pARPacket.PacketType == ARPacket.ARPacketTypes.BinaryReadings ||
                    pARPacket.PacketType == ARPacket.ARPacketTypes.BinarySingleReadType)
            {
                while (pARPacket.GetNextReading(out iReadID, out packetValType, out sVal, out iVal, out strVal, out bVal))
                {
                   if((iPrevReadID != iReadID) && (WriterFormat==ARPacketWriterFormats.FilePerReadIdSourceCSV))
                   { // need to open a new file
                       if (iPrevReadID != -1) objFSWriter.Close();// close the one that is open if one is open
                       objFileStream = new FileStream(this.FilePath(iReadID, pARPacket.SourceSystemAddress), FileMode.Append);
                       objFSWriter=new  StreamWriter(objFileStream);
                       iPrevReadID=iReadID;
                   }
                    WriteSingleReading(iReadID,objFSWriter,packetValType,sVal,iVal,strVal,bVal,pARPacket.PacketType);
                   ++ciReadingsWritten;

                }

            }
                // need to terminate the line if one line per packet
            if (WriterFormat == ARPacketWriterFormats.RowPerPacketFilePerSourceCSV)
                objFSWriter.WriteLine();
            objFSWriter.Close();
            }

        }
        #endregion

        #region Private methods
        private void cWriteHeader(AceBots.ARPacket.ARPacket pPacket, StreamWriter objStream)
        {
            if (IncludeTimeStamp)
                objStream.Write("Date,Time,");
           

            if (WriterFormat == ARPacketWriterFormats.RowPerPacketFilePerSourceCSV)
            {
                for (int i = 0; i < 20; i++)
                {
                    if (pPacket.PacketType != ARPacket.ARPacketTypes.BinarySingleReadType)
                        objStream.Write("ReadID_" + i.ToString() + ",");
                    else if (i == 0)
                        objStream.Write("ReadID,");
                    objStream.Write("Reading_" + i.ToString() + ",");

                }
               
            }
            else
            {
                objStream.Write("ReadID,Reading");
            }
           
            objStream.WriteLine();
        }


        private void WriteSingleReading(short piReadid, StreamWriter pfsWriter, ARPacket.ARPacketValueTypes pValType,
                short psVal, int piVal, string pstrVal, byte pbVal, ARPacket.ARPacketTypes pPacketType)
        {
            if ((IncludeTimeStamp && ciReadingsWritten == 0) ||
                (IncludeTimeStamp && WriterFormat != ARPacketWriterFormats.RowPerPacketFilePerSourceCSV)) 
            {
                pfsWriter.Write(DateTime.Now.ToShortDateString() + "," +
                    DateTime.Now.ToLongTimeString()+",");
            }
            if ((ciReadingsWritten ==0) || 
                (WriterFormat != ARPacketWriterFormats.RowPerPacketFilePerSourceCSV) ||
                  (pPacketType != ARPacket.ARPacketTypes.BinarySingleReadType))
            pfsWriter.Write(piReadid.ToString() + ",");

            // Convert value to a string
            switch (pValType)
	        {
		        case AceBots.ARPacket.ARPacketValueTypes.IsByte:
                    pstrVal = pbVal.ToString();
                 break;
                case AceBots.ARPacket.ARPacketValueTypes.IsShort:
                 pstrVal = (psVal.ToString());
                 break;
                case AceBots.ARPacket.ARPacketValueTypes.IsInt32:
                 pstrVal = (piVal.ToString());
                 break;
                default:
                 break;
	        }
            if (WriterFormat == ARPacketWriterFormats.RowPerPacketFilePerSourceCSV)
                pfsWriter.Write(pstrVal + ",");
            else
                pfsWriter.WriteLine(pstrVal );

        }

        #endregion

    }
}
